package com.hu.hrm.web.controller;

import com.hu.hrm.doc.CourseDoc;
import com.hu.hrm.query.CourseQuery;
import com.hu.hrm.repository.CourseElasticsearchRepository;
import com.hu.hrm.util.AjaxResult;
import com.hu.hrm.util.PageList;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/es")
public class ESController {

    @Autowired
    private CourseElasticsearchRepository courseElasticsearchRepository;

    /** 添加
     *  由于是ES的添加，所以这里添加需要的数据是文档对象、对应的文档对象！
     *  文档对象处理了：在ES上的内容 不会仅仅来源于一个表（如不会仅来与course） 这个文档对象都可以处理好
     *  由于微服务之间不能依赖，这里将Doc抽取成公共模块！
     * @param courseDoc 对应的文档对象
     * @return
     */
    @RequestMapping("/save")
    public AjaxResult save(@RequestBody CourseDoc courseDoc){
        courseElasticsearchRepository.save(courseDoc);
        return AjaxResult.me();
    }

    @PostMapping("/searchCourse")
    public PageList<CourseDoc> searchCourse(@RequestBody CourseQuery courseQuery){
        //查询JSON字符串，对象转成查询对象
        NativeSearchQuery nativeSearchQueryBuilder = createCourseQueryForES(courseQuery).build();

        //执行查询
        Page<CourseDoc> page = courseElasticsearchRepository.search(nativeSearchQueryBuilder);
        //返回结果 ，page转成 PageList
        return new PageList<>(page.getTotalElements() , page.getContent());
    }


    //拼接查询对象courseQuery -> NativeSearchQueryBuilder
    private NativeSearchQueryBuilder createCourseQueryForES(CourseQuery courseQuery) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        //添加条件===============================================================================================================
        //组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // keyword: "java"  : 查询 MathchQuery  - DSL查询
        if(StringUtils.hasLength(courseQuery.getKeyword())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("name",courseQuery.getKeyword()));
        }

        //过滤
        List<QueryBuilder> filter = boolQueryBuilder.filter();

        //productType: ：termQuery
        if(courseQuery.getProductType() != null){
            filter.add(QueryBuilders.termQuery("courseTypeId",courseQuery.getProductType()));
        }

        //priceMax: null : rangeQuery
        if(courseQuery.getPriceMax() != null){
            filter.add(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax()));
        }

        //priceMin: null ：rangeQuery
        if(courseQuery.getPriceMin() != null){
            filter.add(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin()));
        }

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        //添加分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(courseQuery.getPage() - 1,courseQuery.getRows()));
        //添加排序===============================================================================================================
        // sortField:  ; sortType:==
        if(StringUtils.hasLength(courseQuery.getSortField())){
            String sortField = null;
            switch (courseQuery.getSortField().toLowerCase()){
                case "xl": sortField = "buyCount" ; break;
                case "xp": sortField = "onlineDate" ; break;
                case "jg": sortField = "price" ; break;
                case "rq": sortField = "viewCount" ; break;
                case "pl": sortField = "comment" ; break;
                default:sortField = "price" ;
            }
            //排序方式
            SortOrder sortOrder = SortOrder.DESC;
            if(StringUtils.hasLength(courseQuery.getSortType()) && courseQuery.getSortType().toLowerCase().equals("asc")){
                sortOrder = SortOrder.ASC;
            }
            nativeSearchQueryBuilder.withSort(new FieldSortBuilder(sortField).order(sortOrder));
        }

        return nativeSearchQueryBuilder;
    }
}
